package com.wontube.smr.bo.sites.hulu;

import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.wontube.client.extension.utils.DateUtils;
import com.wontube.client.extension.utils.RandomUtils;
import com.wontube.client.extension.utils.StringUtils;
import com.wontube.core.dao.mybatis.QueryExample;
import com.wontube.core.pub.AppEnvironment;
import com.wontube.smr.bo.constants.SiteConstants;
import com.wontube.smr.bo.constants.StandarAreas;
import com.wontube.smr.client.model.po.Movie;
import com.wontube.smr.client.model.po.MovieGenre;
import com.wontube.smr.client.model.po.PopularEpisode;
import com.wontube.smr.client.model.po.RecentEpisode;
import com.wontube.smr.client.model.po.RecentMovie;
import com.wontube.smr.client.model.po.RecentShow;
import com.wontube.smr.client.model.po.TVEpisode;
import com.wontube.smr.client.model.po.TVSeason;
import com.wontube.smr.client.model.po.TVShow;
import com.wontube.smr.client.model.po.TVShowGenre;
import com.wontube.smr.dao.bo.TVSelectDao;
import com.wontube.smr.dao.mapper.MovieGenreMapper;
import com.wontube.smr.dao.mapper.MovieMapper;
import com.wontube.smr.dao.mapper.PopularEpisodeMapper;
import com.wontube.smr.dao.mapper.RecentEpisodeMapper;
import com.wontube.smr.dao.mapper.RecentMovieMapper;
import com.wontube.smr.dao.mapper.RecentShowMapper;
import com.wontube.smr.dao.mapper.TVEpisodeMapper;
import com.wontube.smr.dao.mapper.TVSeasonMapper;
import com.wontube.smr.dao.mapper.TVShowGenreMapper;
import com.wontube.smr.dao.mapper.TVShowMapper;
import com.wontube.smr.pub.DefaultDBHelper;

/**
 * @author tanggf(2012-8-28)
 *
 */
public class HuluObtainBO2 {
	private static final Logger logger = LoggerFactory.getLogger(HuluObtainBO2.class);	
	
	private final static String POPULAR_MOVIE_URL_FORMAT = "http://www.hulu.com/api/2.0/videos.json?order=desc&sort=view_count_today&video_type=feature_film&items_per_page=32&position={}&_user_pgid=1&_content_pgid=67&_device_id=1";
	private final static String RECENT_MOVIE_URL_FORMAT = "http://www.hulu.com/api/2.0/videos.json?order=desc&sort=release&video_type=feature_film&items_per_page=32&position={}&_user_pgid=1&_content_pgid=67&_device_id=1";
	
	private final static String POPULAR_TV_SHOW_URL_FORMAT = "http://www.hulu.com/api/2.0/shows.json?free_only=1&order=desc&sort=view_count_today&video_type=tv&items_per_page=64&position={}&_user_pgid=1&_content_pgid=67&_device_id=1";
	private final static String TV_EPISODE_URL_FORMAT = "http://www.hulu.com/api/2.0/videos.json?free_only=true&include_seasons=true&order=asc&shorter_cache=true&show_id={}&sort=original_premiere_date&video_type[]=episode&video_type[]=game&items_per_page=32&position={}&_user_pgid=1&_content_pgid=67&_device_id=1";
	private final static String RECENT_TV_SHOW_URL_FORMAT = "http://www.hulu.com/api/2.0/shows.json?free_only=1&order=desc&sort=release&video_type=tv&items_per_page=64&position={}&_user_pgid=1&_content_pgid=67&_device_id=1";
	
	private final static String POPULAR_TV_EPISODE_URL_FORMAT = "http://www.hulu.com/api/2.0/videos.json?free_only=1&order=desc&sort=view_count_week&video_type=episode&items_per_page=64&position={}&_user_pgid=1&_content_pgid=67&_device_id=1";
	private final static String RECENT_TV_EPISODE_URL_FORMAT = "http://www.hulu.com/api/2.0/videos_by_show.json?free_only=1&order=desc&sort=release&video_type=episode&items_per_page=64&position={}&_user_pgid=1&_content_pgid=67&_device_id=1";
	
	private static final String DOMAIN = "http://www.hulu.com";
	private final static String HULU_SHOW_IMAGE_URL_FORMAT = "http://ib{}.huluim.com/show/{}?size=220x124";
	private final static String HULU_VIDEO_IMAGE_URL_FORMAT = "http://ib{}.huluim.com/video/{}?size=220x124";	
	
	private final static int MOVIE_PAGE_SIZE = 32;
	private final static int RECENT_MOVIE_PAGE_COUNT = 10; // 32 * 10 = 320
	
	private final static int TV_PAGE_SIZE = 64;
	private final static int RECENT_TV_PAGE_COUNT = 5; // 64 * 5 = 320
	private final static int TV_EP_PAGE_SIZE = 32;
	
	private final static int POPULAR_TV_EP_PAGE_SIZE = 64;
	private final static int POPULAR_TV_EP_PAGE_COUNT = 5; // 64 * 5 = 320
	
	private final static int RECENT_TV_EP_PAGE_SIZE = 64;
	private final static int RECENT_TV_EP_PAGE_COUNT = 5; // 64 * 5 = 320
	

	private HuluObtainBO2() {
	}
	
	/**
	 * grab today popular movies
	 * @return
	 */
	public static int grabAllPopularMovies(){
		int count = 0;
		int offset = 0;
		while(true){
			String url = StringUtils.format(POPULAR_MOVIE_URL_FORMAT, offset);
			int saved = parseAndSaveMovies(url, count);
			count += saved;
			if(saved == 0 || saved < MOVIE_PAGE_SIZE){
				break;
			}
			
			offset += MOVIE_PAGE_SIZE;
		}
		return count;
	}
	
	/**
	 * 更新前32条popular数据, 主要更新排序
	 * @return
	 */
	public static int updatePopularMovies(){			
		String url = StringUtils.format(POPULAR_MOVIE_URL_FORMAT, 0);
		JsonArray array = parse2JsonArray(url);		
		if(array == null){
			return 0;
		}	
		
		int index = 0;
		Date version = DateUtils.getNow();
		SqlSession session = DefaultDBHelper.getBatchSqlSession();
		try {
			MovieMapper mapper = session.getMapper(MovieMapper.class);
			
			for (JsonElement jsonElement : array) {
				JsonObject video = jsonElement.getAsJsonObject().get("video").getAsJsonObject();	
				String movieId = SiteConstants.ID_PREFIX_HULU + video.get("id").getAsString();
				mapper.updateSortIndex(movieId, ++index, version);		
			}	
			
			session.commit();
		} finally {
			session.close();
		}
		
		return index;
	}	
	
	/**
	 * update to recent_movie
	 * @return
	 */
	public static int updateRecentMovies(){	
		int count = 0;		
		for (int i = 0; i < RECENT_MOVIE_PAGE_COUNT; i++) {
			int offset = MOVIE_PAGE_SIZE * i;
			String url = StringUtils.format(RECENT_MOVIE_URL_FORMAT, offset);
			int saved =  parseAndSaveRecentMovies(url, count);
			count += saved;
			if(saved == 0 || saved < MOVIE_PAGE_SIZE){
				break;
			}						
		}	
		
		return count;
	}
	
	//========tv show========
	/**
	 * grab today popular tv show and related episode
	 * @return
	 */
	public static int grabAllPopularTVShows(){		
		int count = 0;
		int offset = 0;
		while(true){
			String url = StringUtils.format(POPULAR_TV_SHOW_URL_FORMAT, offset);
			int saved = parseAndSaveTVShows(url, count);
			count += saved;
			if(saved == 0 || saved < TV_PAGE_SIZE){
				break;
			}			
				
			offset += TV_PAGE_SIZE;
		}
		return count;
	}	
	
	/**
	 * 更新前32条popular数据, 主要更新排序
	 * @return
	 */
	public static int updatePopularTVShows(){		
		String url = StringUtils.format(POPULAR_TV_SHOW_URL_FORMAT, 0);
		JsonArray array = parse2JsonArray(url);
		if(array == null){
			return 0;
		}
		
		int index = 0;
		Date version = DateUtils.getNow();
		SqlSession session = DefaultDBHelper.getBatchSqlSession();
		try {
			TVShowMapper mapper = session.getMapper(TVShowMapper.class);
			
			for (JsonElement jsonElement : array) {
				JsonObject show = jsonElement.getAsJsonObject().get("show").getAsJsonObject();	
				String showId = SiteConstants.ID_PREFIX_HULU + show.get("id").getAsString();
				mapper.updateSortIndex(showId, ++index, version);		
			}	
			
			session.commit();
		} finally {
			session.close();
		}
		
		return index;	
	}

	/**
	 * update to recent_show
	 * @return
	 */
	public static int updateRecentTVShows(){
		int count = 0;		
		for (int i = 0; i < RECENT_TV_PAGE_COUNT; i++) {
			int offset = TV_PAGE_SIZE * i;
			String url = StringUtils.format(RECENT_TV_SHOW_URL_FORMAT, offset);
			int saved =  parseAndSaveRecentTV(url, count);
			count += saved;
			if(saved == 0 || saved < TV_PAGE_SIZE){
				break;
			}			
		}	
		
		return count;
	}
	
	//========tv episode====
	/**
	 * update to popular_episodes
	 * @return
	 */
	public static int updatePopularEpisodes(){
		int count = 0;		
		for (int i = 0; i < POPULAR_TV_EP_PAGE_COUNT; i++) {
			int offset = POPULAR_TV_EP_PAGE_SIZE * i;
			String url = StringUtils.format(POPULAR_TV_EPISODE_URL_FORMAT, offset);
			int saved =  parseAndSaveUpdatingEpisodes("popular", url, count);
			count += saved;
			if(saved == 0 || saved < POPULAR_TV_EP_PAGE_SIZE){
				break;
			}			
		}	
		
		return count;
	}

	/**
	 * update to recent_episode
	 * @return
	 */
	public static int updateRecentTVEpisodes(){
		int count = 0;		
		for (int i = 0; i < RECENT_TV_EP_PAGE_COUNT; i++) {
			int offset = RECENT_TV_EP_PAGE_SIZE * i;
			String url = StringUtils.format(RECENT_TV_EPISODE_URL_FORMAT, offset);
			int saved =  parseAndSaveUpdatingEpisodes("recent", url, count);
			count += saved;
			if(saved == 0 || saved < RECENT_TV_EP_PAGE_SIZE){
				break;
			}			
		}	
		
		return count;
	}
	
	private static int parseAndSaveUpdatingEpisodes(String type, String url, int index) {
		JsonArray array = parse2JsonArray(url);
		if(array == null){
			return 0;
		}
		
		Date version = DateUtils.getNow();
		SqlSession session = DefaultDBHelper.getSqlSession(false);
		try {
			TVShowMapper tvMapper = session.getMapper(TVShowMapper.class);
			TVEpisodeMapper epMapper = session.getMapper(TVEpisodeMapper.class);
			PopularEpisodeMapper popMapper = session.getMapper(PopularEpisodeMapper.class);
			RecentEpisodeMapper recentMapper = session.getMapper(RecentEpisodeMapper.class);
			
			for (JsonElement jsonElement : array) {
				JsonObject video = jsonElement.getAsJsonObject().get("video").getAsJsonObject();	
				TVEpisode ep = null;
				try {
					ep = json2TVEpisode(video, null);
				} catch (Exception e) {					
					logger.error("error happen when parse json to TVEpisode, the url is {}", url, e);
					continue;
				}				
				
				String epId = ep.getId();
				boolean included = true;
				if(epMapper.selectByPrimaryKey(epId) == null){
					String showId = ep.getShowId();
					//本地没数据, 检查TVShow是否存在
					if(tvMapper.selectByPrimaryKey(showId) != null){
						//插入episode
						ep = json2TVEpisode(video, showId);
						epMapper.insert(ep);		
						//TODO 不更新tv_show的总season,总episode数量, 这里不好判断,
						//使用定时器定时统计
					}else{
						included = false;
					}
				}
				
				if(included){
					if("popular".equals(type)){
						//update to popular_episode
						PopularEpisode pe = new PopularEpisode();
						pe.setEpisodeId(epId);
						pe.setSortIndex(++index);
						pe.setVersion(version);
						
						QueryExample ex = new QueryExample();
						ex.or().addCriterion("popular_episode.episode_id=", epId);
						List<PopularEpisode> populars = popMapper.selectByExample(ex);
						if(populars.size() > 0){
							pe.setId(populars.get(0).getId());
							popMapper.updateByPrimaryKey(pe);
						}else{
							pe.setId(UUID.randomUUID().toString());
							popMapper.insert(pe);
						}
					}else if("recent".equals(type)){
						RecentEpisode rep = new RecentEpisode();
						rep.setEpisodeId(epId);
						rep.setSortIndex(++index);
						rep.setVersion(version);
						
						QueryExample ex = new QueryExample();
						ex.or().addCriterion("recent_episode.episode_id=", epId);
						List<RecentEpisode> recents = recentMapper.selectByExample(ex);
						if(recents.size() > 0){
							rep.setId(recents.get(0).getId());
							recentMapper.updateByPrimaryKey(rep);
						}else{
							rep.setId(UUID.randomUUID().toString());
							recentMapper.insert(rep);
						}
					}
				}
			}
			
			session.commit();
		} finally {
			session.close();
		}
		
		return array.size();
	}
	

	private static int parseAndSaveRecentTV(String url, int index) {
		//将recent tv 的排序置后
		int showIndex = 1000;
		
		JsonArray array = parse2JsonArray(url);
		if(array == null){
			return 0;
		}
		
		List<String> showIds = new ArrayList<String>();
		for (JsonElement jsonElement : array) {
			JsonObject show = jsonElement.getAsJsonObject().get("show").getAsJsonObject();	
			String showId = SiteConstants.ID_PREFIX_HULU + show.get("id").getAsString();
			if(TVSelectDao.getTVShow(showId) == null){
				//insert tv shows and episodes					
				boolean aff = saveTVShowWithEpisodes(json2TVShow(show), showIndex);
				if(aff){
					showIds.add(showId);
				}
			}else{
				showIds.add(showId);
			}	
		}
		
		Date version = DateUtils.getNow();
		//更新到recent_show					
		SqlSession session = DefaultDBHelper.getSqlSession(false);
		try {
			
			RecentShowMapper recentMapper = session.getMapper(RecentShowMapper.class);				
			for (String showId : showIds) {
				//update to recent_show
				RecentShow rs = new RecentShow();
				rs.setVersion(version);
				rs.setShowId(showId);
				rs.setSortIndex(++index);	
				
				QueryExample ex = new QueryExample();
				ex.or().addCriterion("recent_show.show_id=", showId);
				List<RecentShow> recents = recentMapper.selectByExample(ex);
				if(recents.size() > 0){
					rs.setId(recents.get(0).getId());
					recentMapper.updateByPrimaryKey(rs);
				}else{
					rs.setId(UUID.randomUUID().toString());
					recentMapper.insert(rs);
				}
			}					
				
			session.commit();
		} finally {
			session.close();
		}			
		
		return showIds.size();
	}
	
	private static int parseAndSaveRecentMovies(String url, int index) {
		//置后排序, 不影响popular movie的排序
		int movieIndex = 1500;
				
		JsonArray array = parse2JsonArray(url);
		int count = 0;
		if(array != null){
			count = array.size();
			Date version = DateUtils.getNow();
			SqlSession session = DefaultDBHelper.getSqlSession(false);			
			try {
				MovieMapper movieMapper = session.getMapper(MovieMapper.class);
				RecentMovieMapper recentMapper = session.getMapper(RecentMovieMapper.class);					
				for (JsonElement jsonElement : array) {
					JsonObject video = jsonElement.getAsJsonObject().get("video").getAsJsonObject();
					String movieId = SiteConstants.ID_PREFIX_HULU + video.get("id").getAsString();
					if(movieMapper.selectByPrimaryKey(movieId) == null){
						Movie movie = json2Movie(video);
						//insert, 置后movie sort_index
						movie.setSortIndex(++movieIndex);
						movieMapper.insert(movie);
					}					
					
					//update recent_movie
					RecentMovie rm = new RecentMovie();
					rm.setMovieId(movieId);
					rm.setVersion(version);
					rm.setSortIndex(++index);
					QueryExample ex = new QueryExample();
					ex.or().addCriterion("recent_movie.movie_id=", movieId);
					List<RecentMovie> recents = recentMapper.selectByExample(ex);
					if(recents.size() > 0){
						rm.setId(recents.get(0).getId());
						recentMapper.updateByPrimaryKey(rm);
					}else{
						rm.setId(UUID.randomUUID().toString());
						recentMapper.insert(rm);
					}
				}
				
				session.commit();
			} finally {
				session.close();
			}
		}
				
		return count;
	}
	
	private static int parseAndSaveTVShows(String url, int index) {
		List<TVShow> shows = new ArrayList<TVShow>();
		JsonArray array = parse2JsonArray(url);				
		if(array == null){		
			return 0;	
		}
		
		for (JsonElement jsonElement : array) {								
			JsonObject show = jsonElement.getAsJsonObject().get("show").getAsJsonObject();								
			shows.add(json2TVShow(show));
		}			
		
		int size = 0;
		for (TVShow show : shows) {
			if(saveTVShowWithEpisodes(show, index)){
				size++;
			}
		}
		
		return size;
	}
	
	private static boolean saveTVShowWithEpisodes(TVShow show, int index){
		Date version = DateUtils.getNow();				
		List<TVEpisode> episodes = grabAllTVEpisodes(show);
		
		boolean aff = false;
		if(episodes.size() > 0){
			String showId = show.getId();
			show.setSortIndex(++index);
			show.setVersion(version);
			show.setAirBeginDate(episodes.get(0).getAirDate());
			
			//save to db
			SqlSession session = DefaultDBHelper.getSqlSession(false);					
			try {
				TVShowMapper showMapper = session.getMapper(TVShowMapper.class);
				TVShowGenreMapper genreMapper = session.getMapper(TVShowGenreMapper.class);
				TVEpisodeMapper epMapper = session.getMapper(TVEpisodeMapper.class);
				
				TVShow tmpShow = showMapper.selectByPrimaryKey(showId);
				if(tmpShow != null){
					showMapper.updateByPrimaryKey(show);
				}else{
					showMapper.insert(show);
					
					//genre
					TVShowGenre tvGenre = new TVShowGenre();
					tvGenre.setGenreName(show.getGenre());
					tvGenre.setShowId(showId);
					tvGenre.setId(UUID.randomUUID().toString());
					
					genreMapper.insert(tvGenre);
				}
				
				//episode
				for (TVEpisode ep : episodes) {
					ep.setVersion(version);
					TVEpisode tmpEp = epMapper.selectByPrimaryKey(ep.getId());
					if(tmpEp != null){
						epMapper.updateByPrimaryKey(ep);
					}else{
						epMapper.insert(ep);
					}
				}
				
				//season 信息
				QueryExample seasonEx = new QueryExample();
				seasonEx.or().addCriterion("tv_season.show_id = ", showId);
				List<Integer> seasons = epMapper.selectSeasons(showId);
				TVSeasonMapper seasonMapper = session.getMapper(TVSeasonMapper.class);
				seasonMapper.deleteByExample(seasonEx);
				for (Integer seasonNo : seasons) {
					seasonEx.clear();
					seasonEx.or().addCriterion("tv_season.show_id = ", showId)
						.addCriterion("tv_season.season_no = ", seasonNo);
					if (seasonMapper.countByExample(seasonEx) < 1) {// 不存在
						TVSeason season = new TVSeason();
						season.setId(UUID.randomUUID().toString());
						season.setShowId(showId);
						season.setSeasonNo(seasonNo);
						season.setVersion(version);
						seasonMapper.insert(season);
					}
				}
				
				session.commit();
			} finally {
				session.close();
			}
			
			aff = true;
		}
		
		return aff;
	}

	private static List<TVEpisode> grabAllTVEpisodes(TVShow show) {		
		List<TVEpisode> episodes = new ArrayList<TVEpisode>();
		String videoId = show.getVideoId();
		String showId = show.getId();
		int offset = 0;
		while(true){
			String url = StringUtils.format(TV_EPISODE_URL_FORMAT, videoId, offset);
			int saved = parseTVEpisodeFromJson(episodes, url, showId);
			if(saved == 0 || saved < TV_EP_PAGE_SIZE){
				break;
			}
			offset += TV_EP_PAGE_SIZE;
		}
		return episodes;
	}

	private static int parseTVEpisodeFromJson(List<TVEpisode> episodes, String url, String showId) {
		JsonArray array = parse2JsonArray(url);
		if(array == null){
			return 0;
		}
		
		for (JsonElement jsonElement : array) {		
			JsonObject video = jsonElement.getAsJsonObject().get("video").getAsJsonObject();	
			TVEpisode ep = null;
			try {
				ep = json2TVEpisode(video, showId);
			} catch (Exception e) {
				logger.error("error happen when parse json to tv episode, url is {}, showId is {}", url, showId);
			}
			if(ep != null){
				episodes.add(ep);
			}
		}
		
		return array.size();
	}
	
	private static String getHuluShowImage(String vid){
		int num = RandomUtils.randomInt(1, 5);
		return StringUtils.format(HULU_SHOW_IMAGE_URL_FORMAT, num, vid);
	}
	
	private static String getHuluVideoImage(String vid){
		int num = RandomUtils.randomInt(1, 5);
		return StringUtils.format(HULU_VIDEO_IMAGE_URL_FORMAT, num, vid);
	}

	private static int parseAndSaveMovies(String url, int index) {
		List<Movie> movies = new ArrayList<Movie>();
		JsonArray array = parse2JsonArray(url);		
		if (array == null) {		
			return 0;	
		}
		
		for (JsonElement jsonElement : array) {
			JsonObject video = jsonElement.getAsJsonObject().get("video").getAsJsonObject();				
			movies.add(json2Movie(video));
		}			
		
		int size = movies.size();
		//save to db
		if(size > 0){
			Date version = DateUtils.getNow();
			SqlSession session = DefaultDBHelper.getSqlSession(false);
			try {
				MovieMapper movieMapper = session.getMapper(MovieMapper.class);
				MovieGenreMapper genreMapper = session.getMapper(MovieGenreMapper.class);
				
				for (Movie movie : movies) {
					movie.setSortIndex(++index);
					movie.setVersion(version);
					String movieId = movie.getId();
					Movie tmpMovie = movieMapper.selectByPrimaryKey(movieId);
					if(tmpMovie != null){
						movieMapper.updateByPrimaryKey(movie);
					}else{
						movieMapper.insert(movie);
						
						//genre
						MovieGenre mg = new MovieGenre();
						mg.setGenreName(movie.getGenre());
						mg.setMovieId(movieId);
						mg.setId(UUID.randomUUID().toString());
						genreMapper.insert(mg);
					}
				}
				
				session.commit();
			} finally {
				session.close();
			}
		}
		
		return size;
	}
	
	private static JsonArray parse2JsonArray(String url){
		HttpURLConnection conn = null;
		InputStreamReader reader = null;
		JsonObject jsonObject = null;
		try {
			conn = (HttpURLConnection) new URL(url).openConnection();
			conn.connect();			
			reader = new InputStreamReader(conn.getInputStream(), AppEnvironment.charsetName);
			JsonParser parser = new JsonParser();
			jsonObject = (JsonObject) parser.parse(reader);			
		} catch (Exception e) {
			logger.error("error happen when parse hulu json response", e);		
		} finally {
			conn.disconnect();
			try {
				if(reader != null){
					reader.close();
				}				
			} catch (IOException e) {				
			}
		}
		
		if(jsonObject != null){
			JsonArray array = jsonObject.get("data").getAsJsonArray();			
			if(array.size() > 0){
				return array;
			}
		}
		
		return null;
	}

	private static Movie json2Movie(JsonObject video){
		Movie movie = new Movie();						
		String vid = video.get("id").getAsString();
		movie.setId(SiteConstants.ID_PREFIX_HULU + vid);					
		movie.setTitle(video.get("title").getAsString());
		movie.setTitleInitial(StringUtils.getInitial(movie.getTitle()));
		movie.setDescription(video.get("description").getAsString());
		movie.setThumbnail(video.get("poster_url").getAsString());
		double duration = video.get("duration").getAsDouble();
		movie.setDuration((int)duration);
		//"released_at": "2009-08-10T04:00:07Z"
		String released = video.get("released_at").getAsString();
		released = released.replace("T", " ").replace("Z", "");
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date airDate = DateUtils.parse(format, released);
		movie.setPublishTime(airDate);					
		
		JsonObject show = video.get("show").getAsJsonObject();
		double rating = show.get("rating").getAsDouble();
		movie.setScore(BigDecimal.valueOf(rating));
		String genre = show.get("genre").getAsString();
		//修正genre
		movie.setGenre(HuluMovieGenres.remendGenre(genre));
		
		movie.setArea(StandarAreas.DEFAULT);
		movie.setItemUrl(DOMAIN + "/watch/" + vid);
		movie.setVideoId(vid);
		movie.setWebsite(SiteConstants.WEBSITE_HULU);
		movie.setMovieType(Movie.TYPE_MOVIE);
		
		return movie;
	}
	
	private static TVShow json2TVShow(JsonObject show){
		String vid = show.get("id").getAsString();
		String name = show.get("name").getAsString();
		String safeName = show.get("canonical_name").getAsString();
		double rating = show.get("rating").getAsDouble();
		int seasonCnt = show.get("seasons_count").getAsInt();
		int epCnt = show.get("episodes_count").getAsInt();
		String genre = show.get("genre").getAsString();
		JsonElement jsonDesc = show.get("description");
		String desc = (jsonDesc == null  || jsonDesc.isJsonNull())? "" : jsonDesc.getAsString();
		
		TVShow tv = new TVShow();
		tv.setId(SiteConstants.ID_PREFIX_HULU + vid);					
		tv.setDescription(desc);
		tv.setEpisodeCnt(epCnt);
		//修正genre
		tv.setGenre(HuluTVGenres.remendGenre(genre));
		tv.setItemUrl(DOMAIN + "/" + safeName);
		tv.setName(name);
		tv.setTitleInitial(StringUtils.getInitial(name));
		tv.setScore(BigDecimal.valueOf(rating));
		tv.setSeasonCount(seasonCnt);
		tv.setVideoId(vid);
		tv.setThumbnail(getHuluShowImage(vid));
		
		tv.setWebsite(SiteConstants.WEBSITE_HULU);
		tv.setArea(StandarAreas.DEFAULT);
		
		return tv;
	}
	
	private static TVEpisode json2TVEpisode(JsonObject video, String showId){
		TVEpisode ep = new TVEpisode();
		int season = video.get("season_number").getAsInt();
		int part = video.get("episode_number").getAsInt();
		ep.setPart(part);
		ep.setSeason(season);
		
		if(showId == null){
			//只需要确定
			showId = SiteConstants.ID_PREFIX_HULU + video.get("show_id").getAsString();
			ep.setShowId(showId);
			ep.setId(showId + "E" + season + "E" + part);
			return ep;
		}
		
		ep.setId(showId + "E" + season + "E" + part);
		ep.setShowId(showId);
		
		String vid = video.get("id").getAsString();
		String cid = video.get("content_id").getAsString();
		String title = video.get("title").getAsString();
		String desc = video.get("description").getAsString();		
		double rating = video.get("rating").getAsDouble();
		double duration = video.get("duration").getAsDouble();
		//"released_at": "2009-08-10T04:00:07Z"
		String released = video.get("released_at").getAsString();
		released = released.replace("T", " ").replace("Z", "");
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date airDate = DateUtils.parse(format, released);	
		
		ep.setWebsite(SiteConstants.WEBSITE_HULU);
		ep.setVideoId(vid);
		ep.setUrl(DOMAIN + "/watch/" + vid);
		ep.setIntroduction(desc);
		
		ep.setScore(BigDecimal.valueOf(rating));
		ep.setDuration((int)duration);
		
		ep.setEpisodeName(title);
		ep.setThumbnail(getHuluVideoImage(cid));
		ep.setAirDate(airDate);		
		
		return ep;
	}
	
	
	public static void main(String[] args) {		
		updateRecentTVShows();
	}
}
